package k8sdriver

import (
	v1 "gluenet/internal/agent/api/meta/v1"
	"gluenet/internal/agent/depend"
	"gluenet/internal/agent/driver"
	"gluenet/internal/agent/driver/k8sdriver/data"
	"gluenet/internal/agent/driver/k8sdriver/option"
	"gluenet/internal/agent/driver/k8sdriver/simple"
	"io"

	"github.com/spf13/viper"
)

type K8sDriver interface {
	Dynamic
	Pods
	NameSpaces
	Services

	ParseMainfest(mainfest string) []string
	ListNodes(opts option.ListOptions) (*data.SimpleNodesList, error)
}

type Pods interface {
	ListPods(namespace string, opts option.ListOptions) *data.SimplePodListResult

	LabelPod(
		namespace,
		podName string,
		labels map[string]string,
	) error

	UnLabelPod(
		namespace,
		podName string,
		labels []string,
	) error
}

type Services interface {
	GetService(serviceName string, opts option.GetServiceOptions) (*data.SimpleService, error)

	DeleteService(nameSpace, serviceName string) error
}

type NameSpaces interface {
	IsNameSpaceExist(nameSpace string) bool

	CreateNameSpace(nameSpace string) error

	DeleteNameSpace(namespace string) error

	ListNameSpace() ([]string, error)
}

type Dynamic interface {
	Apply(br io.Reader, opts *v1.ApplyOptions) error
	Delete(br io.Reader, opts *v1.DeleteOptions) error

	ApplyFromDir(filePath string, opts *v1.ApplyOptions) error
	DeleteFromDir(filePath string, opts *v1.DeleteOptions) error
}

func init() {
	depend.Provide(NewK8sConfig)
	depend.Provide(NewK8sDriver)
}

const (
	keyK8sConfig = driver.KeyDriverPerfix + `k8s`
)

type K8sConfig struct {
	KubePath string `mapstructure:"kube_path"`
}

func NewK8sConfig(vp *viper.Viper) (*K8sConfig, error) {
	cfg := new(K8sConfig)
	if err := vp.UnmarshalKey(keyK8sConfig, cfg); err != nil {
		return nil, err
	}
	return cfg, nil
}

func NewK8sDriver(cfg *K8sConfig) (K8sDriver, error) {
	return simple.NewSimpleK8sDriver(cfg.KubePath)
}
